﻿using Alipay.AopSdk.Core.Util;
using Alipay.EasySDK.Util;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace WebApplication1.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class AlipayController : ControllerBase
    {
        [HttpGet]
        public IActionResult GetPhoneNumber(string openapiResult)
        {
            //string openapiResult = "{\"response\":\"A3sQ8r88GWj0yg+k0wiK6Ww+Et9fNF3fqbwvxFdnhYC6MQwPLCdE6zi4XqfVVclgF+MGPqLY8KYRIIyZQTI4E0G/mxzYHsim2dcVOiWFAcr5A6qC7fgU76lI+Ce12uI+Z+R5JESgTti6XTiIuIWtL5tycqOLbX3Jg3pHGdqC1Zc=\",\"sign\":\"c1S1Ty12GCmSw8Nc/gdZry1fjkZLw/4MDH5LvpHeFcPL01TyuXZjas/WL6J+MXJ9Vn24huoKldPcXOuFmH+l4RwJTiZnL9tnr62Afr/QHTNTQPkt810VY7NLaEz9KutPZfJUwo9DIxOZil3RRl0Y93qkklXYMVRbtQnGPsIh7Cz98CPe3amxYpn6F0Ba49WgFAFB1wTX8TuJuTQn7QBo0tqXTdV9ILqyXfn8FsHSkBdHBbJesmSnMMFwFj8w6GoZ6Wk+KAMCtgjq33KfvmHLLFa05qP9RuFzq/gmq7TeANQSHpGLtll6r7V8muCufQ2epClwcEmwkYECq0DDAKzMwQ==\"}";
            string aesKey = "TLhb6K68n6YK9Uu1G5odow=="; // 你的AES密钥 (base64)

            //小程序通过 my.getPhoneNumber 获取到加密数据，详见获取会员手机号接入文档
            string res = "";
            JObject jObj = null;
            //1. 获取验签和解密所需要的参数
            try
            {
                jObj = (JObject)JsonConvert.DeserializeObject(openapiResult);
            }
            catch (Exception ex)
            {
                throw new Exception("获取验签和解密所需要的参数失败", ex);
            }

            string signType;
            if (openapiResult.Contains("sign_type"))
            {
                signType = jObj["sign_type"].ToString();
            }
            else
            {
                signType = "RSA2";
            }

            string charset;
            if (openapiResult.Contains("charset"))
            {
                charset = jObj["charset"].ToString();
            }
            else
            {
                charset = "UTF-8";
            }

            string encryptType;
            if (openapiResult.Contains("encrypt_type"))
            {
                encryptType = jObj["encrypt_type"].ToString();
            }
            else
            {
                encryptType = "AES";
            }

            string sign = jObj["sign"].ToString();
            string content = jObj["response"].ToString();

            //如果密文的
            bool isDataEncrypted = !content.StartsWith("{", StringComparison.Ordinal);
            bool signCheckPass = false;

            //2. 验签
            string signContent = content;
            //RSA2支付宝公钥（不是应用公钥），在控制台-小程序-开发设置-开发设置-接口加签方式-设置/查看
            string signVeriKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjyhrOXnfVHkQb6LfJBVrskHUcqj5xoqOqNrmAT11RyKYsC9DpoYArljy7abwlImTciOWy7U5yWYwSl3Vn3RnUqYEoGmqDLuwrpUIbxQwswGQPSi+BUGkOiUdi3HeJ1hlgqNWL+DK2iCkn4fKgELrik+tDYi8B5JnCL5gZNbK0TCmcd97CaHw8T7OSMAj1BWkOtuzluHdroel3kX8M+OhgiGrKZ4vwe3Y2sSE7qmSww+Oi/cE4aVHyyNmkpI3QJ2v65oGBf6R5KtllzI76JUAfDp1uUGSjpl2XiSEDV9l5/L0ciZ+FOxmkVG2K6q5VoJJtZRJwNxTnlt93or040XmvwIDAQAB";
            //填小程序设置的AES密钥。注意：若AES密钥中存在反斜杠"\\"会导致解密报错，需删除反斜杠或更改没有反斜杠的AES密钥
            string decryptKey = aesKey;
            //如果是加密的报文则需要在密文的前后添加双引号
            if (isDataEncrypted)
            {
                signContent = "\"" + signContent + "\"";
            }
            try
            {
                signCheckPass = AlipaySignature.RSACheckContent(signContent, sign, signVeriKey, charset, signType, false);
                Console.WriteLine("RSA2验签结果：" + signCheckPass);
            }
            catch (Exception ex)
            {
                //验签异常, 日志
                throw new Exception("验签失败", ex);
            }
            if (!signCheckPass)
            {
                //验签不通过（异常或者报文被篡改），终止流程（不需要做解密）
                throw new Exception("验签失败");
            }

            //3. 解密
            string plainData = null;
            if (isDataEncrypted)
            {
                try
                {

                    plainData = AesDencrypt(decryptKey, content, charset);

                    Console.WriteLine("AES解密结果：" + plainData);
                }
                catch (Exception ex)
                {
                    //解密异常, 记录日志
                    throw new Exception("解密异常", ex);
                }
            }
            else
            {
                plainData = content;
            }
            return Ok(plainData);
        }
        private static readonly byte[] AES_IV = initIv(16);
        private static byte[] initIv(int blockSize)
        {
            byte[] array = new byte[blockSize];
            for (int i = 0; i < blockSize; i++)
            {
                array[i] = 0;
            }

            return array;
        }
        public static string AesDencrypt(string encryptKey, string bizContent, string charset)
        {
            byte[] key = Convert.FromBase64String(encryptKey);
            byte[] array = Convert.FromBase64String(bizContent);
            RijndaelManaged rijndaelManaged = new RijndaelManaged();
            rijndaelManaged.Key = key;
            rijndaelManaged.Mode = CipherMode.CBC;
            rijndaelManaged.Padding = PaddingMode.PKCS7;
            rijndaelManaged.IV = AES_IV;
            byte[] bytes = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV).TransformFinalBlock(array, 0, array.Length);
            if (string.IsNullOrEmpty(charset))
            {
                return Encoding.UTF8.GetString(bytes);
            }

            return Encoding.GetEncoding(charset).GetString(bytes);
        }

        
           
    }
}
